Secure Channels: SSH and TLS
A secure channel is a means of data transmission between two channels, and it provides the following all of the following three: confidentiality, authenticity and integrity. Secure channels are implemented from the transport layer and above; and the two protocols we will be looking at are SSH and TLS.
Attacker Model
Before we start delving into the functioning of the SSH and TLS protocols, it is important to define what is the attacker capable of. We consider a secure channel safe against the following attacker model:
- Attacker has full control over the network (i.e., an attacker can sniff and examine all of the packets in the communication)
- Attacker can intercept, modify and send any message
- However, an attacker cannot decipher any of the encrypted content (as he doesn't possess the keys that encrypt the content)
This is called the Dolev-Yao model (default attacker model in distributed systems).
SSH
SSH stands for Secure SHell, and it is a protocol designed to create a secure channel between two hosts, and allows the client host to login to the SSH server, and perform actions in that machine (e.g.: file transfer, shell usage, and more).
SSH was introduced to replace protocols like Telnet, that allowed you to create login to another machine and control it remotely, but had a major problem: they lacked security mechanisms. SSH ensures confidentiality and integrity in the communication, and allows both parties in the communication to authenticate to each other.
How does SSH work?
The establishment of a SSH connection can be divided in three steps:
- Verification of server's identity by the client
- Negotiation of a secret key for encryption of all messages
- Authentication of the client
SSH is a protocol that will make use of both asymmetric cryptography (using public/private key pairs, for steps 1 and possibly 3) and symmetric cryptography (for step 2, and for all further communication).
We will now take a look at each step of the connection process.
1. Verification of Server Identity
The client starts by initiating a SSH connection request to the server. During this step, it is important that the client confirms the true identity of the server. Depending on whether it is the first time the client connects to this server, two things can happen:
- If the client has never connected to this server, it will verify the server's identity using the server's public key. Once that is done, the server is added to the
~/.ssh/known_hosts
file on the client machine for future logins. - If the client has connected to this server before, it will verify the server's identity with the information in the
known_hosts
file.
Once this step is concluded, we can move to the next step.
2. Negotiation of Secret Key
Client and server will now begin the negotiation of a secret key, to encrypt further messages. This is done using the Diffie-Hellman (or Elliptic-Curve DH) algorithm. After the secret key to use is agreed between the two parties, all further communication will be encrypted using that key.
3. Client Authentication
The last step in the connection process is the authentication of the client to the server. This can be done in two ways:
- Using password authentication (less secure)
- Using SSH Keys (more secure)
In password authentication, the client will simply send the password of the user that it is trying to login as in the server machine; if the password is correct. This is less secure, because password authentication is more vulnerable to attacks (brute force, phishing, etc.) than other alternatives like public-key authentication.
The other alternative is using SSH Keys. SSH keys are simply private/public key-pairs. To authenticate the client using SSH keys, a key-pair should be generated by the client, and the private key should be kept in the ~/.ssh/
folder in the client machine. On the other hand, the public key generated should be added to the ~/.ssh/authorized_keys
file.
In the case that SSH keys are being used, the authentication process will look something like this:
- The client begins by sending a key ID, corresponding to the key ID of its public key
- The server will check its
authorized_keys
file, and search for the received key ID - If a match is found, then the server will generate a random number, and encrypt that random number with the client's public key. This encrypted message is then sent to the client
- After receiving this, the client will decrypt the generated random number with its private key. It will then compute the MD5 hash of this number plus the secret key agreed previously, and send it to the server
- The server will then receive this value, compute the MD5 hash of the original random number plus the agreed secret key, and check if these values match. If they do, then the client has proven it is the owner of the private key that is the pair to the public key with the ID sent in step 1.
SSH Tunneling
We can also leverage the SSH protocol for another purpose : tunneling. Tunneling is a technology that allows to transform the communication of one protocol into another protocol, while being transparent to the applications. For example, I may want to make a HTTP request to port 80 in a remote server using a ssh tunnel. This way, the request will be transmitted as a normal SSH message to port 22 in the server, and then when received by the sshd server can be forwarded to port 80.
For tunneling to work, there needs to be a mapping of local ports to remote ports. In the example below, we want to create an IMAP (mail protocol) connection using a SSH tunnel. Therefore, in the SSH tunnel configuration, we tell ssh client to listen to port 220 (port for this protocol) and to forward it to port 220 in the remote machine. This way, the outgoing IMAP traffic in the client will be captured by the SSH client, sent through a SSH connection, and the sshd server in the remote machine will decrypt it and forward it to its local port 220.
Fig.1: SSH tunnel configuration example
Fig.2: Diagram of the traffic flowing through a SSH tunnel
SSH Tunneling: Advantages and Disadvantages
Advantages of SSH tunneling:
- It's transparent to applications
- Allows to enforce confidentiality, integrity and authenticity to protocols that don't natively support these security features
Disadvantages:
- Makes it harder for admins to do port management
- Low flexibility for developers and users
TLS
TLS stands for Transport Layer Security; it is a protocol designed to create a secure channel for communication across the Internet, and it provides confidentiality, integrity, authenticity and key distribution. TLS "sits" between layers 4 and 5 of the OSI model, and it can be used by any TCP protocol to enforce security. This means that, unlike its predecessor SSL, that was aimed to only be used with HTTP communication, TLS is used by a variety of services and protocols running on the Internet (HTTP, SMTP, IMAP, POP3, etc.)
It is important to notice that TLS is just a protocol; not an API. In SSL, the reference API used was SSLref (used by Netscape Navigator, a web browser responsible for the early developments in SSL). For TLS, there are many APIs that applications can use, like:
- OpenSSL
- GnuTLS
- SSLeay
- Mbed TLS
- Java Secure Socket Extension (JSSE)
For HTTPS communication, the default port used is 443. It is also possible to upgrade any text-based connection to use TLS, with STARTTLS (used by many protocols, like SMTP, IMAP, POP, FTP, IRC, etc.)